#pragma once
/***********************************************************
This class defines the interfaces of Automated Calibrated Method for the NCUC model. 
The genetic algorithms used in this implementation is the Simple GAs.
And the genome used is the GABin2DecGenome, which utilize binary strings to represent
decimal numbers.
The objective funtion used is CE. (Coeficient of Efficiency)
The scaling scheme is the Sigma truncation scaling scheme.
The score output file is "score.txt".
***********************************************************/
/**************************************************************
Author: Chun-Ming Wang
Date of Modification: 22/11/2007 (dd/mm/yyyy)
***************************************************************/
#include "..\NCUCModel\Misc.h"
#include <algorithm>
#include <ga\ga.h>
#include "..\NCUCModel\NCUCModel.h"
#include "AttachedData.h"
#include "StdAfx.h"
#ifndef _ACMSIMPLEGAB2D
#define _ACMSIMPLEGAB2D
const string fileName = "score.txt";
class ACMSimpleGAB2D
{	
public:
	static float Objective(GAGenome&g);
public:
	ACMSimpleGAB2D(void);
	virtual ~ACMSimpleGAB2D(void);

	// function pointer declaration
	// for the performance criterion functio for observed runoff
	// and simulated runoff
	typedef float (*pEval)(const vector<double>& obs,
		const vector<double>& sim);
	// a packed envolve function
	void evolve();
	// parameters of genetic algorithms
	const unsigned int nPopulation() const;
	void nPopulation(const unsigned int& n);
	const unsigned int nGeneration() const;
	void nGeneration(const unsigned int& n);
	const double pMutation() const;
	void pMutation(const double& p);
	const double pCrossover() const;
	void pCrossover(const double& p);
	// set the genome information
	void configure(const vector<const GenomeType*>& info,
		pEval eval = coe);
	// get the best individual
	const vector<double> bestIndividual();
	// set the objective function
	// void eval(pEval ptr);
	// to minimize the objective function
	void minimize();
	// to maximizie the objective function
	void maximize();
	// set the observed runoff in the AttachedData
	void obsRunoff(const vector<double>& obs);
	// set the observed rainfall in the AttachedData
	void rainfall(const vector<double>& p);
	// set the model in the AttachedData
	void model(NCUCModel* p);
	// What is this?
	void initialize();

	//-----------------------------------------------
	// for testing the GASimpleGA
	//-----------------------------------------------
#ifdef _GASIMPLEGA_TEST
	void phenotype();
	void userData(float* p);
#endif
protected:
	// initialize the genetic algorithms
	//ACMSimpleGAB2D& operator=(const ACMSimpleGAB2D& rhs);
	// return the performance criterion function
	const pEval eval() const;  
private:
	pEval m_eval;
	GASimpleGA* mp_GA;
	GABin2DecGenome* mp_Genome;
	GABin2DecPhenotype m_Phenotype;
	GASigmaTruncationScaling m_Scaling;
	AttachedData m_Adata;
#ifdef _GASIMPLEGA_TEST
	float* mp_userData;
#endif
};
#endif